import { Article } from '@/entity/Article';
import { Categories } from '@/entity/Categories';
import { Tag } from '@/entity/Tag';
import { Comment } from '@/entity/Comment';
import { User } from '@/entity/User';
import { Service, Inject } from 'typedi'
import { Like } from "typeorm"
import { Entity } from '@/utils/orm'
import { Segment } from '@/utils/segment'
import { JsonResult, msgList, res } from '@/utils/jsonResult';
import { Article as ResArticle, comment as commentType, categories} from '@/m_res/Article';
import { CommentParams } from '@/model/request/Comment';
import { Token } from '@/m_req/Token'
import moment from 'moment';


@Service()
export class ArticleDao {

    @Inject()
    orm!: Entity

    @Inject()
    json!: JsonResult<any>;

    @Inject()
    segment!: Segment

    async pushCommentDao(params: CommentParams, token: Token) {
        let res = await this.orm.source()
            .insert()
            .into(Comment)
            .values({ 
                comment_text: params.comment_text, 
                comment_time: moment().valueOf(),
                comment_father_id: params.comment_father_id,
                article_id: params.article_id,
                user_id: token.user_id,
                user_reply_id: params.user_reply_id
            })
            .execute();
            return this.json.success(null, msgList.pushMessageSuccess)
            
    }


    async GetArticleDao(): Promise<res<Array<ResArticle>>> {
        let res = await this.orm.repository(Article).getMany();
        res.forEach(v => {
            v.article_text = v.article_text.substr(0,100)
        })
        return this.json.success(res);
    }


    async GetArticleInfoDao(id: number): Promise<res<null>> {
        let data = await this.orm.get(Article).findOne({ where: { article_id: id } })

        if (data != null) {
            let newData: ResArticle = <ResArticle><unknown>data

            newData.categories_id = await this.orm.get(Categories).find({
                where: (<string>data.categories_id).split(",").map(v => {
                    return { categories_id: Number(v) }
                })
            })

            newData.tag_id = await this.orm.get(Tag).find({
                where: (<string>data.tag_id).split(",").map(v => {
                    return { tag_id: Number(v) }
                })
            })

            let comment = <commentType[]><unknown>await this.orm.get(Comment).find({ 
                where: { article_id: id } 
            })

            for (let i = 0; i < comment.length; i++) {
                let me = await this.orm.get(User).findOne({
                    select: { user_name: true, user_img: true },
                    where: { user_id: comment[i].user_id }
                })

                let you = await this.orm.get(User).findOne({
                    select: { user_name: true },
                    where: { user_id: comment[i].user_reply_id }
                })

                if (me != null || you != null) {
                    for (const key in me) {
                        comment[i][key] = me[key]
                    }
    
                    for (const key in you) {
                        comment[i]["user_reply_name"] = you[key]
                    }
                }
                
            }
            

            let leaveOne: commentType[] = [];
            comment.forEach(v => {
                if (v.comment_father_id == 0) {
                    v.comment_children = []
                    leaveOne.push(<commentType><unknown>v)
                }
            })

            leaveOne.forEach(v => {
                comment.forEach(j => {
                    if (v.comment_id == j.comment_father_id) {
                    // @ts-ignore
                        v.comment_children.push(j)
                    }
                }) 
            })

            newData.article_comment = leaveOne;

            return this.json.success(newData)
        }

        return this.json.error(null, "id不存在")
    }

    async GetCategoriesListDao(): Promise<res<categories[]>>{
        return this.json.success(await this.orm.get(Categories).find({
            order: {
                categories_id: "DESC"
            },
        }))
    }


    async GetCategoriesInfoDao(id: number): Promise<res<ResArticle[]>>{
        let res = await this.orm.get(Article).findBy({
            categories_id: Like(`%${id}%`),
        })
        return this.json.success(res)
    }


    async SearchDao(word: string): Promise<res<ResArticle[]>>{
        let sql: string = ""
        this.segment.ik(word).forEach(v => {
            sql += ` or article_title like '%${v.w}%'`
        })

        let res = await this.orm.repository(Article)
        .where(sql.replace("or", ""))
        .getMany()
        return this.json.success(res)
    }

}